package com.feng.cloud.system.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.feng.cloud.common.exception.system.ParameterException;
import com.feng.cloud.common.exception.system.SystemStatus;
import com.feng.cloud.system.dto.DeptTree;
import com.feng.cloud.system.dto.Tree;
import com.feng.cloud.system.entity.Dept;
import com.feng.cloud.system.mapper.DeptMapper;
import com.feng.cloud.system.utils.TreeUtils;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * @ClassName DeptService
 * @Description TODO
 * @Author Better Feng
 * @Date 2019/12/25 10:29
 * @Version 1.0
 **/
@Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
@RequiredArgsConstructor
public class DeptService extends ServiceImpl<DeptMapper, Dept> {

    /**
     * 查询列表
     * @param dept Dept
     * @return List<Dept>
     */
    public List<Dept> selectList(Dept dept) {
        LambdaQueryWrapper<Dept> queryWrapper = new LambdaQueryWrapper<>();
        String deptName = dept.getDeptName();
        queryWrapper.like(StringUtils.isNotBlank(deptName), Dept::getDeptName, deptName);
        return this.baseMapper.selectList(queryWrapper);
    }

    /**
     * 查询部门树
     * @param dept Dept
     * @return List<Tree<Dept>>
     */
    public List<DeptTree> selectDeptTree(Dept dept) {
        List<DeptTree> deptTreeList = Collections.emptyList();
        List<Dept> deptList = this.selectList(dept);
        if (CollectionUtils.isEmpty(deptList)) {
            return deptTreeList;
        }
        // 构建树
        return buildTrees(deptList);
    }

    private List<DeptTree> buildTrees(List<Dept> deptList) {
        List<DeptTree> trees = new ArrayList<>();
        deptList.forEach(dept -> {
            DeptTree tree = new DeptTree();
            tree.setId(dept.getDeptId().toString());
            tree.setParentId(dept.getParentId().toString());
            tree.setLabel(dept.getDeptName());
            tree.setOrderNum(dept.getOrderNum());
            trees.add(tree);
        });
        List<? extends Tree> build = TreeUtils.build(trees);
        return (List<DeptTree>) build;
    }

    public void addDept(Dept dept) {
        if (dept.getParentId() == null) {
            dept.setParentId(0L);
        }
        dept.setCreateTime(LocalDateTime.now());
        this.baseMapper.insert(dept);
    }

    public void updateDept(Dept dept) {
        Long deptId = dept.getDeptId();
        if (deptId == null) {
            throw new ParameterException(SystemStatus.DEPT_ID_EMPTY);
        }
        Long parentId = dept.getParentId();
        if (parentId == null) {
            dept.setParentId(0L);
        } else {
            if (deptId.longValue() == parentId) {
                dept.setParentId(0L);
            }
        }
        dept.setModifyTime(LocalDateTime.now());
        this.baseMapper.updateById(dept);
    }

    @Transactional
    public void deleteDept(List<String> idList) {
        // 递归删除部门
        this.delete(idList);
    }

    private void delete(List<String> idList) {
        this.removeByIds(idList);
        LambdaQueryWrapper<Dept> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(Dept::getParentId, idList);
        List<Dept> deptList = this.baseMapper.selectList(queryWrapper);
        if (!CollectionUtils.isEmpty(deptList)) {
            List<String> deptIdList = new ArrayList<>();
            deptList.forEach(d -> deptIdList.add(String.valueOf(d.getDeptId())));
            this.delete(deptIdList);
        }
    }
}
